﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using pub.CmdUI.Cmd;
using pub.CmdUI.UI.Control;
using pub.Functions;
using todo.Dialog;
using todo.Model;
using todo.Persistence;

namespace todo.Cmd.Tool
{
    public class ArchiveCmd : DefaultCmd
    {
        public override void Execute(IControlUI controlUi)
        {
            var todos = App.MainForm.GetTodos();
            var doneItems = CollectTodosByCheckedFlag(todos, 1);
            if (doneItems.Count == 0)
            {
                var msg = "No done item found, nothing to archive.";
#if zh
                msg = "未发现已完成项，没有可归档的内容。";
#endif
                MessageBox.Show(msg,
                        App.Title, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            //
            if (!SaveArchive(doneItems))
            {
                return;
            }

            //
            PromptRemoveArchivedItems(todos);
            Console.WriteLine("..");
        }

        private static bool SaveArchive(List<Todo> doneItems)
        {
            var dlgSave = new SaveFileDialog();
            dlgSave.InitialDirectory = Path.GetDirectoryName(App.TodoListFile);
            dlgSave.DefaultExt = "todolist";
            dlgSave.OverwritePrompt = false;
            dlgSave.Filter = "TodoList files (*.todolist)|*.todolist|All files (*.*)|*.*";
            dlgSave.FileName = Path.GetFileNameWithoutExtension(App.TodoListFile) +
                               ".archive.todolist";
//                ".archive_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".todolist";
            var dr = dlgSave.ShowDialog();
            if (dr != DialogResult.OK)
            {
                return false;
            }
            var archiveFileName = dlgSave.FileName;
            TodoList todoList = null;
            if (System.IO.File.Exists(archiveFileName))
            {
                var dlg = new ArchiveActionDialog();
                dlg.ShowDialog();
                dr = dlg.DialogResult;

//                dr =
//                    MessageBox.Show(
//                        "File exists, do you want to append archived items into it?" +
//                        "\n(Yes for append, No for overwrite)",
//                        App.Title, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                if (dr == DialogResult.Cancel)
                {
                    return false;
                }
                todoList = TodoListReader.Read(archiveFileName);
                if (dr == DialogResult.Yes)
                {
                    var todos = todoList.Todos ?? new List<Todo>();
                    for (var n = doneItems.Count - 1; n >= 0; --n)
                    {
                        todos.Insert(0, doneItems[n]);
                    }
                }
                else
                {
                    todoList.Todos = doneItems;
                }
            }
            else
            {
                todoList = VarFuncs.DeepClone(App.TodoList);
                todoList.Todos = doneItems;
            }

            TodoListWriter.Save(todoList, archiveFileName);

            return true;
        }

        private void PromptRemoveArchivedItems(List<Todo> todos)
        {
            var msg = "Acchive complete.\n" + "Remove archived items from current todolist?";
#if zh
            msg = "归档完成。将已归档项目从当前待办列表中移除？";
#endif
            var dr = MessageBox.Show(msg,
                    App.Title, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (dr != DialogResult.Yes)
            {
                return;
            }
            var undoneItems = CollectTodosByCheckedFlag(todos, 0);

            App.TodoList.Todos = undoneItems;
            App.Dirty = true;

            App.MainForm.ReloadTodoList();
        }

        private List<Todo> CollectTodosByCheckedFlag(List<Todo> todos, int checkedValue)
        {
            todos = VarFuncs.DeepClone(todos);
            for (var n = todos.Count - 1; n >= 0; --n)
            {
                if (!FilterTodoWithCheckedFlag(todos[n], checkedValue))
                {
                    todos.RemoveAt(n);
                }
            }

            return todos;
        }

        // return true if keep
        private bool FilterTodoWithCheckedFlag(Todo todo, int checkedValue)
        {
            var childTodos = todo.Todos;
            if (childTodos == null)
            {
                childTodos = new List<Todo>();
            }
            for (var n = childTodos.Count - 1; n >= 0; --n)
            {
                if (!FilterTodoWithCheckedFlag(childTodos[n], checkedValue))
                {
                    childTodos.RemoveAt(n);
                }
            }
            return childTodos.Count > 0 || todo.Checked == checkedValue;
        }
    }
}